package Application;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import VectorApproach.TrajVector;
import VectorApproach.VClusterBulk;
import XmlLoader.FGObjProcess;
import XmlLoader.FGObjectTrajectoryStructure;
import XmlLoader.Position;
import XmlLoader.Size;
import Cluster.ClusterBulk;
import Cluster.HashClusterRange;
import Cluster.Trajectory;
import MyLoader.MyLoader;

public class ImageGenerator {
	public static Color[] listColor = {Color.pink, Color.CYAN, Color.green,
		Color.LIGHT_GRAY, Color.magenta, Color.ORANGE, Color.BLACK, Color.RED,
		Color.YELLOW, Color.WHITE};
	
	public static void DrawOneTraj(Trajectory getTraj, Graphics2D g) {
		int indexP = 0;
		while(indexP < getTraj.GET001_length() - 1) {
			Position getCP = getTraj.GET002_point(indexP);
			Position getNP = getTraj.GET002_point(indexP + 1);
			Size getCS = getTraj.GET004_size(indexP);
			Size getNS = getTraj.GET004_size(indexP + 1);
			
			g.drawLine(getCP.x, getCP.y, getNP.x, getNP.y);
			//g.drawRect(getCS.posLeftTop.x, getCS.posLeftTop.y, getCS.width, getCS.height);
			//g.drawRect(getNS.posLeftTop.x, getNS.posLeftTop.y, getNS.width, getNS.height);
			
			indexP = indexP + 1;
		}
	}
	
	public static void GenCluster(String filePath, ArrayList<ClusterBulk> listCluster,
			int length, int width, String background) {
		BufferedImage img = new BufferedImage(length, width, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = img.createGraphics();
		g.fillRect(0, 0, length, width);
		g.setBackground(Color.WHITE);
		//create txt file for recording cluster info
		File fileCList = new File(filePath.replace(".png", ".txt"));
		FileWriter fwrite = null;
		try {
			fwrite = new FileWriter(fileCList);
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		//draw background
		try {
			g.drawImage(ImageIO.read(new File(background)), 0, 0, null);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		int indexC = 0, indexT = 0, indexP = 0;
		while(indexC < listCluster.size()) {
			try {
				fwrite.append("C" + indexC + "\n");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			g.setColor(new Color((int) (Math.random() * 256), (int) (Math.random() * 256), (int) (Math.random() * 256)));
			indexT = 0;
			while(indexT < listCluster.get(indexC).GET002_listTraj().size()) {
				Trajectory getTraj = listCluster.get(indexC).GET002_listTraj().get(indexT);
				try {
					fwrite.append(getTraj.GET003_trajID() + "\n");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				if(getTraj.GET001_length() == 1) {
					Position getP = getTraj.GET002_point(0);
					g.drawLine(getP.x, getP.y, getP.x, getP.y);
				}
				else{
					//draw center of cluster
					indexP = 0;
					while(indexP < getTraj.GET001_length() - 1) {
						Position getCP = getTraj.GET002_point(indexP);
						Position getNP = getTraj.GET002_point(indexP + 1);
						if(indexP == 0) {
							g.drawOval(getCP.x, getCP.y, 5, 5);
						}
						else if(indexP == getTraj.GET001_length() - 2) {
							g.drawRect(getNP.x, getNP.y, 6, 6);
						}
						g.drawLine(getCP.x, getCP.y, getNP.x, getNP.y);
						indexP = indexP + 1;
					}
				}
				indexT = indexT + 1;
			}
			indexC = indexC + 1;
		}
		try {
			ImageIO.write(img, "png", new File(filePath));
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
		try {
			fwrite.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			return;
		}
	}
	
	public static void GenVCluster(String filePath, ArrayList<VClusterBulk> listCluster,
			int length, int width, String background) {
		BufferedImage img = new BufferedImage(length, width, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = img.createGraphics();
		g.fillRect(0, 0, length, width);
		g.setBackground(Color.WHITE);
		//create txt file for recording cluster info
		File fileCList = new File(filePath.replace(".png", ".txt"));
		FileWriter fwrite = null;
		try {
			fwrite = new FileWriter(fileCList);
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		//draw background
		try {
			g.drawImage(ImageIO.read(new File(background)), 0, 0, null);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		int indexC = 0, indexT = 0, indexP = 0;
		while(indexC < listCluster.size()) {
			try {
				fwrite.append("C" + indexC + "\n");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			g.setColor(new Color((int) (Math.random() * 256), (int) (Math.random() * 256), (int) (Math.random() * 256)));
			indexT = 0;
			while(indexT < listCluster.get(indexC).GET002_listTraj().size()) {
				TrajVector getTraj = listCluster.get(indexC).GET002_listTraj().get(indexT);
				try {
					fwrite.append(getTraj.GET001_trajID() + " " + getTraj.GET002_trajSegID()+ "\n");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				Position getCP = getTraj.getStartPos();
				Position getNP = getTraj.getEndPos();
				if(getCP.ACT002_isInRange(new Position(0,0), new Position(length, width)) && getNP.ACT002_isInRange(new Position(0,0), new Position(length, width)))
				{
					g.drawLine(getCP.x, getCP.y, getNP.x, getNP.y);
				}
				indexT = indexT + 1;
			}
			indexC = indexC + 1;
		}
		try {
			fwrite.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			File fdraw = new File(filePath);
			ImageIO.write(img, "png", fdraw);
			Thread.sleep(50);
		}
		catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			return;
		}
		
	}
	
	public static void GenClusterOneByOne(String filePath, ArrayList<ClusterBulk> listCluster,
			int length, int width, String background) {
		BufferedImage img = new BufferedImage(length, width, BufferedImage.TYPE_INT_RGB);
		int indexC = 0, indexT = 0;
		while(indexC < listCluster.size()) {
			//create cluster folder
			String filePathCluster = filePath + "/" + indexC;
			new File(filePathCluster).mkdir();
			//get main trajectory
			Trajectory mainTraj = listCluster.get(indexC).GET001_mainTraj();
			indexT = 0;
			while(indexT < listCluster.get(indexC).GET002_listTraj().size()) {
				//get one trajectory
				Trajectory getTraj = listCluster.get(indexC).GET002_listTraj().get(indexT);
				
				Graphics2D g = img.createGraphics();
				g.fillRect(0, 0, length, width);
				g.setBackground(Color.WHITE);
				try {
					g.drawImage(ImageIO.read(new File(background)), 0, 0, null);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			
				if(mainTraj != null) {
					g.setColor(ImageGenerator.listColor[1]);
					ImageGenerator.DrawOneTraj(mainTraj, g);
				}
				g.setColor(ImageGenerator.listColor[2]);
				
				if(getTraj.GET001_length() == 1) {
					Position getP = getTraj.GET002_point(0);
					g.drawLine(getP.x, getP.y, getP.x, getP.y);
				}
				else{
					ImageGenerator.DrawOneTraj(getTraj, g);
				}
				try {
					ImageIO.write(img, "png", new File(filePathCluster + "/" + indexT + "_" + getTraj.GET003_trajID() + ".png"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				indexT = indexT + 1;
			}
			indexC = indexC + 1;
		}
	}
	
	public static ArrayList<ClusterBulk> GenClusterOneByOneFromFile(List<FGObjectTrajectoryStructure> list, 
			String filePathRead, String filePathWrite, int length, int width, 
			String background) {
		String readStr = null;
		ClusterBulk cb = null;
		ArrayList<ClusterBulk> listCb = new ArrayList<ClusterBulk>();
		
		File dirWrite = new File(filePathWrite);
		if(!dirWrite.isDirectory()) {
			dirWrite.mkdir();
		}
		
		int indexTraj = 0;
		try {
			BufferedReader br = new BufferedReader(new FileReader(filePathRead));
			while((readStr = br.readLine()) != null) {
				if(readStr.startsWith("C")) {
					if(cb != null) {
						listCb.add(cb);
					}
					cb = new ClusterBulk(Integer.parseInt(readStr.substring(1)), -1);
				}
				else {
					indexTraj = Integer.parseInt(readStr);
					FGObjectTrajectoryStructure getTraj = list.get(indexTraj);
					cb.ACT001_insertNewTraj(new Trajectory(getTraj, 0, 0, getTraj.GET002_nNumberOfPoint()));
				}
			}
			listCb.add(cb);
			//ImageGenerator.GenClusterOneByOne(filePathWrite, listCb, length, width, background);
		
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return listCb;
	}
	
	public static void GenTraj(String filePath, List<FGObjectTrajectoryStructure> list,
			int length, int width, String background) {
		BufferedImage img = new BufferedImage(length, width, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = img.createGraphics();
		g.fillRect(0, 0, length, width);
		g.setBackground(Color.WHITE);
		g.setColor(Color.BLACK);
		
		try {
			//draw background
			g.drawImage(ImageIO.read(new File(background)), 0, 0, null);
			//draw trajectory
			int indexTraj = 0;
			while(indexTraj < list.size()) {
				FGObjectTrajectoryStructure ftrajs = list.get(indexTraj);
				int indexPoint = 1;
				while(indexPoint < ftrajs.GET002_nNumberOfPoint()) {
					Position ptail = ftrajs.GET003_elementIn_list_fGObject(indexPoint).GET001_centerReal();
					Position phead = ftrajs.GET003_elementIn_list_fGObject(indexPoint - 1).GET001_centerReal();
					g.drawLine(phead.x, phead.y, ptail.x, ptail.y);
					indexPoint = indexPoint + 1;
				}
				indexTraj = indexTraj + 1;
			}
			ImageIO.write(img, "png", new File(filePath));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void GenTrajV(String filePath, List<TrajVector> list,
			int length, int width, String background, VClusterBulk vb) {
		BufferedImage img = new BufferedImage(length, width, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = img.createGraphics();
		g.fillRect(0, 0, length, width);
		g.setBackground(Color.WHITE);
		g.setColor(Color.BLACK);
		
		try {
			//draw background
			g.drawImage(ImageIO.read(new File(background)), 0, 0, null);
			//draw trajectory
			int indexTraj = 0;
			while(indexTraj < list.size()) {
				TrajVector ftrajs = list.get(indexTraj);
				Position phead = ftrajs.getStartPos();
				Position ptail = ftrajs.getEndPos();
				g.drawLine(phead.x, phead.y, ptail.x, ptail.y);
				indexTraj = indexTraj + 1;
			}
			//draw splite line
			if(vb != null) {
				vb.ACT007_drawRoadRange(g, length, width);
			}
			ImageIO.write(img, "png", new File(filePath));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		//generate list trajectory index
		System.out.println("Generate trajectory index file");
		new ReadFileGenerateor().ACT001_genFile(args[0], Integer.parseInt(args[1]), Integer.parseInt(args[2]));
										
		//load trajectory xml data
		System.out.println("Load trajectory xml file");
		FGObjProcess fgObj = new FGObjProcess(args[3]);
		List<String> list_objIndex = fgObj.ACT004_getStringList(args[0]);
		List<FGObjectTrajectoryStructure> listAll = new MyLoader().ACT001_getListOfObj(args[3], list_objIndex);
		
		//trajectory structure transformation
		ArrayList<Trajectory> listTraj = new ArrayList<Trajectory>();
		int index = 0;
		while(index < listAll.size()) {
			listTraj.add(new Trajectory(listAll.get(index), 0, 0, listAll.get(index).GET002_nNumberOfPoint()));
			index = index + 1;
		}
		
		ClusterBulk cb = new ClusterBulk(0, -1);
		index = 0;
		while(index < listTraj.size()) {
			cb.ACT001_insertNewTraj(listTraj.get(index));
			index = index + 1;
		}
		ArrayList<ClusterBulk> listCb = new ArrayList<ClusterBulk>();
		listCb.add(cb);
		
		ImageGenerator.GenClusterOneByOne("C:\\Users\\test\\Desktop\\Result", listCb, 720, 480, args[4]);
	}
}
